package com.xiao.mall.foundation.service;

import com.xiao.mall.foundation.service.dto.EnumType;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author zhoushaofeng
 */
@Service
public class MetaDataService {

    public List<EnumType> findAllEnumObjects(String[] basePackages) {
        List<EnumType> enumObjectDtoList = new ArrayList<>();
        for (String packageName : basePackages) {
            enumObjectDtoList.addAll(scanEnumTypes(packageName));
        }

        return enumObjectDtoList;
    }

    public List<EnumType> scanEnumTypes(String packageName) {
        List<EnumType> enumTypeList = new ArrayList<>();
        ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
        provider.addIncludeFilter(new AnnotationTypeFilter((com.xiao.mall.foundation.annotation.EnumType.class)));
        Set<BeanDefinition> components = provider.findCandidateComponents(packageName);
        for (BeanDefinition beanDefinition : components) {
            Class clz = null;
            try {
                clz = Class.forName(beanDefinition.getBeanClassName());
                if (clz.isEnum()) {
                    com.xiao.mall.foundation.annotation.EnumType enumObject = AnnotationUtils.findAnnotation(clz, com.xiao.mall.foundation.annotation.EnumType.class);
                    String name = enumObject.value();
                    EnumType enumType = EnumType.builder()
                        .name(StringUtils.hasLength(name) ? name : clz.getSimpleName())
                        .values(clz.getEnumConstants())
                        .build();

                    enumTypeList.add(enumType);
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

        return enumTypeList;
    }
}
